package common;

import interfaces.HttpHeader;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.xiaoleilu.hutool.FileUtil;
import com.xiaoleilu.hutool.Log;
import com.xiaoleilu.hutool.StrUtil;

import utils.CommonUtil;
import action.Controller;
import bean.Request;
import bean.Response;

public class ServerThread{
	private Socket socket;
	private InputStream in;
	private OutputStream out;
	private BufferedWriter bw; 
	private String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	public ServerThread(Socket socket){
		this.socket = socket;
		try {
			this.in = socket.getInputStream();
			this.out = socket.getOutputStream();
			bw = new BufferedWriter(new OutputStreamWriter(out,"UTF-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void process() {
			try{
				String readStr = read();
				if(!StrUtil.isEmpty(readStr)){
					readStr = URLDecoder.decode(readStr, "UTF-8");
					Log.info("读到的数据:\r\n"+readStr);
					
					Request req = CommonUtil.str2Req(readStr);
					Log.info("requestURL="+req.getUrl());
					Response resp = new Response();
					resp.setWriter(bw);
					if(!StrUtil.isEmpty(req.getUrl()) ){
						processRequest(req,resp);
					}
					
				}
				
				this.close();
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				this.close();
			}
	}
	
	private void processRequest(Request req,Response resp) throws IOException, InstantiationException, IllegalAccessException{
		String url = req.getUrl();
		String url2 = url.substring(url.lastIndexOf("/")+1);
		Log.debug("url2={}", url2);
		if(url.endsWith(".html")){
			String body = FileUtil.readString(path+"webContent"+req.getUrl(),"UTF-8");
			if(!StrUtil.isEmpty(body)){
				body = URLDecoder.decode(body,"UTF-8");
				Log.info("返回给客户端的body=\r\n"+body);
				resp.setHttpVersion("HTTP/1.1");
				resp.setStatusCode("200");
				resp.setStatus("OK");
				resp.setHeader(HttpHeader.DATE, new Date().toString());
				resp.setHeader(HttpHeader.CONTENT_TYPE, "text/html;charset=UTF-8");
				resp.setHeader(HttpHeader.CONTENT_LENGTH, body.getBytes().length);
			}else{
				this.render404(resp);
			}
			this.write(resp, body);
			
		}else if(!url2.contains(".")){
			for(Iterator keyIt = HandlerMapping.getRouterKey().iterator() ; keyIt.hasNext();){
				String key = (String) keyIt.next();
				Log.debug("url--indexof={}", url.indexOf(key));
				if(url.indexOf(key) > -1){
					Class clazz = HandlerMapping.getRouterClass(key);
					Controller controller = (Controller) clazz.newInstance();
					String method = url.substring(url.indexOf(key)+key.length());
					Log.info("method={}", method);
					controller.excute(req, resp,method,clazz);
				}
			}
		}else if(isImgEnd(url)){
			String imgName = url.substring(url.lastIndexOf("/"));
			byte[] body = FileUtil.readBytes(new File("F:/Pictures/htmlsave"+imgName));
			Log.info("向客户端发送图片数据-->");
			resp.setHttpVersion("HTTP/1.1");
			resp.setStatusCode("200");
			resp.setStatus("ok");
			resp.setHeader(HttpHeader.DATE, new Date().toString());
			resp.setHeader(HttpHeader.CONTENT_TYPE, " image/*");
			resp.setHeader(HttpHeader.CONTENT_LENGTH, body.length);
			resp.setHeader(HttpHeader.CONNECTION, "close");
			this.write(CommonUtil.resp2Str(resp));
			if(body.length > 0){
				this.write(body);
				this.write(resp, body);
			}
			
		}
		
		
	}
	private String read(){
		StringBuffer sb = new StringBuffer();
		try{
			byte[] b = new byte[in.available()];
			in.read(b);
			sb.append(new String(b));
		}catch(IOException e){
			e.printStackTrace();
		}
		return sb.toString();
		
	}
	private void write(Response resp, String body){
		this.write(CommonUtil.resp2Str(resp));
		this.write(body);
	}
	private void write(Response resp, byte[] body){
		this.write(CommonUtil.resp2Str(resp));
		this.write(body);
	}
	private void write(String sendData){
		try{
			bw.write(sendData);
			bw.flush();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	private void write(byte[] sendData){
		try{
			out.write(sendData);;
			out.flush();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	private void close(){
		try {
			bw.close();
			in.close();
			out.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void render404(Response resp) throws IOException{
		String body = FileUtil.readString(path+"webContent"+"/404.html","UTF-8");
		Log.info("返回给客户端的body-404=\r\n"+body);
		resp.setHttpVersion("HTTP/1.1");
		resp.setStatusCode("404");
		resp.setStatus("Not Found");
		resp.setHeader(HttpHeader.DATE, new Date().toString());
		resp.setHeader(HttpHeader.CONTENT_TYPE, "text/html;charset=UTF-8");
		resp.setHeader(HttpHeader.CONTENT_LENGTH, body.getBytes().length);
		resp.setHeader(HttpHeader.CONNECTION, "close");
		resp.setBody(body);
	}
	
	private boolean isImgEnd(String imgName){
		imgName = imgName.toLowerCase();
		if(imgName.endsWith("bmp") || imgName.endsWith("jpg") || imgName.endsWith("jpeg") || imgName.endsWith("png") || imgName.endsWith("gif")){
			return true;
		}
		
		return false;
	}
}
